package com.tencent.qf.common.gateway.midapi;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.tencent.qf.common.gateway.midapi.dto.CommonRequest;

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.Map;
import java.util.TreeMap;

public class MidApiUtils {

    public static void sign(CommonRequest request, String appkey, String appSecret) {
        request.setAppkey(appkey);
        request.setTime(LocalDateTime.now().toEpochSecond(ZoneOffset.of("+8")));
        request.setSign(null);
        String requestBody = JSON.toJSONString(request);

        // ascii排序、拼接、md5
        TreeMap<String, Object> treeMap = JSON.parseObject(requestBody, new TypeReference<TreeMap<String, Object>>() {
        });
        StringBuilder waitEncrypted = new StringBuilder();
        for (Map.Entry<String, Object> entry : treeMap.entrySet()) {
            Object value = entry.getValue();
            if (value == null) {
                continue;
            }
            if (ObjectUtil.isBasicType(value) || value instanceof String) {
                waitEncrypted.append(value);
            } else {
                waitEncrypted.append(JSON.toJSONString(value));
            }
        }
        waitEncrypted.append(appSecret);

        try {
            MessageDigest messageDigest = MessageDigest.getInstance("md5");
            messageDigest.update(waitEncrypted.toString().getBytes("utf-8"));
            String sign = getFormattedText(messageDigest.digest());
            request.setSign(sign);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
    }

    private static String getFormattedText(byte[] digest) {
        StringBuffer buffer = new StringBuffer();
        //把每一个byte，做一个与运算，0xff
        for (byte b : digest) {
            int number = b & 0xff;//加盐
            String str = Integer.toHexString(number);
            if (str.length() == 1) {
                buffer.append("0");
            }
            buffer.append(str);
        }
        //标准的md5加密后的结果
        return buffer.toString();
    }
}
